#include "ssiot/settings.h"
#include <fstream>
#include "ssiot/ssiot.h"
#include "ssiot/msgbus.h"

Settings::Settings()
{

}

Settings::~Settings()
{

}

nlohmann::json Settings::getSettings(std::string model)
{
	return settings_[model];
}

void Settings::LoadFromFile(std::string filename)
{
	try {
		filename_ = filename;
		std::ifstream f(filename_);
		settings_ = nlohmann::json::parse(f);
		
	}
	catch (...) {
		fprintf(stderr, "load from file error. %s", filename.c_str());
	}
}

void Settings::SaveToFile()
{
	try {
		std::ofstream o(filename_);
		o << std::setw(4) << settings_ << std::endl;
	}
	catch (...) {
		fprintf(stderr, "save from file error. %s", filename_.c_str());
	}
}

void  Settings::LoadSettings(std::string model, nlohmann::json& cfg) 
{
	nlohmann::json m = settings_[model];
	if (!m.empty()) {
		cfg.merge_patch(m);
	}
	else {
		settings_[model] = cfg;
	}
}

void Settings::SyncSettings(std::string model, nlohmann::json& cfg)
{
	nlohmann::json plat = CheckOutSettings(model);
	nlohmann::json mem = settings_[model];

	mem.merge_patch(cfg);

	if (!plat.empty()) {
		mem.merge_patch(plat);
	}

	settings_[model] = mem;

	//fprintf(stderr, "%s", settings_.dump().c_str());

	SaveToFile();

	CommitSettings(model, mem);

	cfg = mem;
}


nlohmann::json Settings::CheckOutSettings(std::string model) 
{
	nlohmann::json req;
	req["path"] = model;

	IoTMsg msg(SSIOT_CONFIG_GET, "", "", req);
	IoTMsg ack = SSIoT::INST()->msgbug()->SyncPublish(msg);
	if (ack.code != 200) {
		fprintf(stderr, "check out settings error. %d", ack.code);
		return "";
	}

	return ack.data[model];
}

void Settings::CommitSettings(std::string model, nlohmann::json cfg)
{
	nlohmann::json obj;
	obj[model] = cfg;
	IoTMsg msg(SSIOT_CONFIG_SET, "", "", obj);
	IoTMsg ack = SSIoT::INST()->msgbug()->SyncPublish(msg);
	if (ack.code != 200) {
		fprintf(stderr, "commit settings error. %d", ack.code);
		return;
	}
}
